#ifndef TIC_CROW_H
#define TIC_CROW_H

#include "json11/json11.hpp"
#include "crow.h"
#include <ros/ros.h>
#include <thread>
#include <geometry_msgs/PoseWithCovarianceStamped.h>

#include <dynamic_reconfigure/server.h>

#include <diagnostic_msgs/DiagnosticStatus.h>
#include <geometry_msgs/Twist.h>

#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>

#include <geometry_msgs/PointStamped.h>
#include <std_msgs/String.h>
#include <std_msgs/Bool.h>
// #include"log/ticlog.h"

#include <pthread.h>

#include <movemotor_presisecontrol/StartRotate.h>
#include <movemotor_presisecontrol/StopRotate.h>
#include <movemotor_presisecontrol/CheckRotate.h>

#include <opencv2/opencv.hpp>
#include <cstring>
#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;

#define BUFSZ 100

using namespace std;
using namespace json11;

namespace tic_crow{
	enum BoardCmd
	{
		brush_level,
		brush_lift,
		water_spray,
		wiper_lift,
		vacuum_level,
		shake_level
	};//键盘控制

	struct BoardCmd_type
	{
		uint8_t brushLevel;
		uint8_t brushLift;
		uint8_t waterSpray;
		uint8_t wiperLift;
		uint8_t vacuum;
		uint8_t shakeLevel;
	};

	typedef struct _poseinfo{

		float poseX;
		float poseY;
		int height;
		int weight;
		float originX;
		float originY;
	}poseinfo;

	class AppCrow
	{
	public:
		//构造函数
		AppCrow();

		//析构函数
		~AppCrow();

		//tic_crow方法
		void tic_crow();

		//判断进程是否存在，不存在进程是true
		bool ProcessIsRun(const char *proc);

		//文件重命名
		bool RenameFile(const char* new_name,const char* old_name);
		
		//获取文件路径
		void Getfilepath(const char *path, const char *filename,  char *filepath);

		//删除文件
		int DeleteFile(const char* path);
		
		bool monitor_file(const char* path);

		vector<string> getFileName(string Path);

		vector<string> getPathName(string Path);

		Point2f TransPose(poseinfo p, float t_x, float t_y);

		int Denoising(string path, poseinfo p);

	private:
		ros::NodeHandle n;
		ros::Publisher vel_pub;
		ros::Publisher initialpose_pub;
		ros::Publisher finish_pathrecord;
		ros::Publisher boardcmdPub;
		ros::Publisher pub_task;
		ros::Publisher stop_task;

		ros::ServiceClient Rotate_client;
		ros::ServiceClient checkRotate_client;
		ros::ServiceClient parameters_client;

		BoardCmd_type bcmd;

		diagnostic_msgs::DiagnosticStatus msg;
    	diagnostic_msgs::KeyValue kv;

		dynamic_reconfigure::Reconfigure srv;
		dynamic_reconfigure::IntParameter temp;

		crow::SimpleApp app;

		std::string map_flag_;

		vector<Point2f> points;

	};

class get_robot_pose
{
public:
	get_robot_pose():finish_handle(false){
		ros::NodeHandle n;
		ROS_INFO("geting and handle robot_pose");
		h_robot_pose = n.subscribe("/robot_pose", 1, &get_robot_pose::callBack, this);
	}
	void callBack(const geometry_msgs::PoseWithCovarianceStamped &msg_robotpose){
		x = msg_robotpose.pose.pose.position.x;
		y = msg_robotpose.pose.pose.position.y;
		finish_handle = true;
	}
public:
	ros::Subscriber h_robot_pose;

	float x;
	float y;

	bool finish_handle;
};

enum TeackTaskStatus
	{
		taskCurrentProgress,
		taskAllProgress,
		taskCount,
		taskAllCount
	};
class handle_task_status{
public:
	handle_task_status():finish_handle(false)
	{
		ros::NodeHandle n;
     	ROS_INFO("handle task the task status");
		h_task = n.subscribe("/teach_task_status", 1, &handle_task_status::callBack, this);
	}
	void callBack(const diagnostic_msgs::DiagnosticStatus &msg){
		cout<<"msg.values.at(taskCount).value"<<msg.values.at(taskCount).value<<endl;
		cout<<"msg.values.at(taskAllCount).value"<<msg.values.at(taskAllCount).value<<endl;
		taskCount=atoi(msg.values.at(taskCount).value.c_str());
		taskAllCount=atoi(msg.values.at(taskAllCount).value.c_str());

		finish_handle = true;
	}
public:
	ros::Subscriber h_task;	

	int taskCount;//已经执行次数
	int taskAllCount;//任务执行次数

	bool finish_handle;
};

}
#endif 